﻿using AdminSystem.Domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AdminSystem.EntityFrameworkCore
{
    public class SoftDeleteInterceptor : SaveChangesInterceptor
    {
        public override InterceptionResult<int> SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
        {
            OnSavingChanges(eventData);
            return base.SavingChanges(eventData, result);
        }

        public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result,
            CancellationToken cancellationToken = new CancellationToken())
        {
            OnSavingChanges(eventData);
            return base.SavingChangesAsync(eventData, result, cancellationToken);
        }

        private static void OnSavingChanges(DbContextEventData eventData)
        {
            ArgumentNullException.ThrowIfNull(eventData.Context);
            eventData.Context.ChangeTracker.DetectChanges();
            foreach (var entityEntry in eventData.Context.ChangeTracker.Entries())
            {
                if (entityEntry is { State: EntityState.Added, Entity: AuditFields softAddEntity })
                {
                    softAddEntity.CreateTime = DateTime.Now;
                    softAddEntity.CreateName = "Admin";
                }

                if (entityEntry is { State: EntityState.Modified, Entity: AuditFields softModifyEntity })
                {
                    softModifyEntity.ModifyTime = DateTime.Now;
                    softModifyEntity.ModifyName = "Admin";
                }

                if (entityEntry is { State: EntityState.Deleted, Entity: AuditFields softDeleteEntity })
                {
                    softDeleteEntity.IsDeleted = true;
                    softDeleteEntity.DeletedTime = DateTime.UtcNow;
                    softDeleteEntity.DeletedName = "Admin";
                    entityEntry.State = EntityState.Modified;
                }
            }
        }
    }
}
